/*oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO*/
//								Battery Module
/*oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO*/


/*oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO*/
//							Includes And Defines
/*oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO*/
#include "Types.h"
#include <WinSock2.h>
#include "ServerClientTools.h"
#include "SocketSendRecvTools.h"
#include "Hw4RandomNumbers.h"
#include "GeneralFunctions.h"


#define DEBUG_MODE

/*oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO*/
//						Internal Structs Decleration
/*oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO*/
// TAcceptConncectionsArgs is a struct designated to send arguments to the AcceptConnections thread.
// It is used internaly in this module only.
typedef struct 
{
	SOCKET MainSocket;
	TInterceptorsList *InterceptorsList;
	TPosition BatteryPosition;
} TAcceptConncectionsArgs;


/*oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO*/
//					Internal Functions Declerations
/*oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO*/

/*
 * GetInterceptorByRocketID
 * =========================
 * Function Description: This function searches for an interceptor in the interceptors list based on the rocket ID of the chased rocket.
 * Arguments: InterceptorsList		A pointer to the head of the interceptors list
 * 			  RocketID				The ID of the rocket chased by the interceptor.
 * Return Value: A pointer to the interceptor if found, or NULL if not found.
 */
TInterceptor* GetInterceptorByRocketID(TInterceptorsList *InterceptorsList, int RocketID);


/*
 * NotifyInterceptorToSwitchBattery
 * =========================
 * Function Description: Notifies an interceptor to switch battery, and deletes the interceptor from the interceptors list.
 * Arguments:   ChasedRocketID				ID of the rocket chased by the interceptor
 				NewBatteryIP				The new battery's IP
 				NewBatteryPort				The new battery's port number
 				InterceptorsList			A pointer to the interceptors list
 * Return Value: TRUE if successful and FALSE on error. 
 */
BOOL NotifyInterceptorToSwitchBattery(int ChasedRocketID, char *NewBatteryIP, int NewBatteryPort, TInterceptorsList *InterceptorsList);


/*
 * LaunchInterceptor
 * =========================
 * Function Description: Launches an interceptor towards a rocket if an interceptor is available.
 * Arguments: RocketVelocity		The chased rocket velocity
 * 			  RocketPosition		The chased rocket position
			  RocketID 				The chased rocket ID
			  InterceptorsList		A pointer to the interceptors list.
 * Return Value: TRUE if successful and FALSE on error or if no interceptors are available for launch.
 */	
BOOL LaunchInterceptor(TVelocity RocketVelocity, TPosition RocketPosition, int RocketID, TInterceptorsList* InterceptorsList);


/*
 * SendLaunchRequestResToManager
 * =========================
 * Function Description: Sends the result of the launch request to the manager.
 * Arguments: RequestRes		The launch request's result
 * 			  ManagerSocket		The manager's socket
 * Return Value: TRUE on success and FALSE on error.
 */
BOOL SendLaunchRequestResToManager(BOOL RequestRes, SOCKET ManagerSocket);


/*
 * AcceptConnectionsFromInterceptorsThread
 * =========================
 * Function Description: A main function for the thread responsible to accept connections from the interceptors.
 * Arguments: AcceptConnectionsArgs		A struct containing the information needed to accept connections from interceptors. See more details in header
 */
void AcceptConnectionsFromInterceptorsThread(TAcceptConncectionsArgs *AcceptConnectionsArgs);

/*
 * AddInterceptorToBattery
 * =========================
 * Function Description: Adds a new interceptor to the battery linked list.
 * Arguments: InterceptorsList		A pointer to the interceptors list.
 * Return Value: A pointer to the first element in the list.
 */
TInterceptor* AddInterceptorToBattery(TInterceptorsList* InterceptorsList);

/*
 * DeleteInterceptor
 * =========================
 * Function Description: Deletes an interceptor from the interceptors linked list.
 * Arguments: InterceptorsList		A pointer to the interceptors list.
 * 			  InterceptorToDelete		A pointer to the interceptor we want to delete.
 */
void DeleteInterceptor(TInterceptorsList *InterceptorsList, TInterceptor *InterceptorToDelete);

/*
 * SelfDistructInterceptor
 * =========================
 * Function Description: Notifies an interceptor that it failed and should self destruct, then deletes the interceptor from the interceptors list.
 * Arguments: InterceptorsList		A pointer to the interceptors list
 * 			  ChasedRocketID		The chased rocket ID.	
 * Return Value: TRUE if successful and FALSE if not.
 */
BOOL SelfDistructInterceptor(TInterceptorsList* InterceptorsList, int ChasedRocketID) ;

/*
 * NotifyInterceptorsOnEndOfRound
 * =========================
 * Function Description: Notifies all interceptors that the round has ended.
 * Arguments: InterceptorsList		A pointer to the interceptors list.
 * Return Value: TRUE if successful and FALSE if not.
 */
void NotifyInterceptorsOnEndOfRound(TInterceptorsList *InterceptorsList);


/*oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO*/
//					END OF Internal Functions Declerations
/*oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO*/

/*oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO*/
//								Locals
/*oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO*/

BOOL StartUpEnded;
SOCKET ManagerSocket;

/*oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO*/
//					Main Battery Function Implementation
/*oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO*/
void MainBattery(int argc, char *argv[])
{
	// accept arguments and declare arguments.
	char *SelfIP = argv[2];
	int SelfPort = atoi(argv[3]);
	char *ClockIP = argv[4];
	int ClockPort = atoi(argv[5]);
	char *ManagerIP = argv[6];
	int ManagerPort = atoi(argv[7]);
	TPosition BatteryPosition;

	SOCKET ClockSocket;
	SOCKET MainSocket;
	HANDLE AcceptConnectcionsThreadHandle;
	TAcceptConncectionsArgs AcceptConncectionsArgs;
	TInterceptorsList InterceptorsList;
	
	TActionType ActionType = ACTION_BEGINNING_OF_ROUND;
	int RoundNum;

	BatteryPosition.x = atof(argv[8]);
	BatteryPosition.y = atof(argv[9]);

	InterceptorsList.FirstInterceptor = NULL;
	InterceptorsList.NumOfFlyingInterceptors = 0;
	InterceptorsList.NumOfInterceptors = 0;
	
	StartUpEnded = FALSE;
	// END accept arguments and declare arguments.

	// Start up sequence
	printf("DEBUG: Starting start up sequence\n");

	// set up server and accept connections from interceptors
	MainSocket = StartServer(SelfIP, SelfPort);
	printf("DEBUG: Started a server, now waiting for clients to connect\n");

	// define arguments for the accept connections thread
	AcceptConncectionsArgs.MainSocket = MainSocket;
	AcceptConncectionsArgs.InterceptorsList = &InterceptorsList;
	AcceptConncectionsArgs.BatteryPosition = BatteryPosition;
	
	AcceptConnectcionsThreadHandle = CreateThreadSimple((LPTHREAD_START_ROUTINE)AcceptConnectionsFromInterceptorsThread, &AcceptConncectionsArgs, NULL);
	printf("DEBUG: Waiting for interceptors to connect\n");

	// connect to manager
	printf("DEBUG: Trying to connect to Manager\n");
	ManagerSocket = StartClientAndConnectToServer(ManagerIP, ManagerPort);
	printf("DEBUG: Sending position to manager: (%g, %g)\n", BatteryPosition.x, BatteryPosition.y);
	SendVector(BatteryPosition, ManagerSocket);
	printf("DEBUG: Sending IP to manager: %s\n", SelfIP);
	SendString(SelfIP, ManagerSocket);
	printf("DEBUG: Sending port to manager: %d\n", SelfPort);
	SendInteger(SelfPort, ManagerSocket);
	printf("DEBUG: Sent battery info to manager\n");
	
	// connect to clock
	printf("DEBUG: Trying to connect to Clock\n");
	ClockSocket = StartClientAndConnectToServer(ClockIP, ClockPort);

	printf("DEBUG: Connected to Manager and Clock.\n");
	FinishedStartUpSequence();
	StartUpEnded = TRUE; 
	// END OF Start up sequence

	// Main loop - this loop accepts orders until the round is finished
	RoundNum = WaitForClockToNotifyBeginningOfRound(ClockSocket);
	if (RoundNum == -1)
	{
		PrintErrorAndExit(ERROR_RECEIVING_MESSAGE);
	}
	while (1)
	{
		// Receive action from manager
		ReceiveActionType(&ActionType, ManagerSocket);
		switch (ActionType)
		{
			case ACTION_END_OF_ROUND:
				printf("Self IP: %s\n", SelfIP);
				printf("Num of flying interceptors: %d\n", InterceptorsList.NumOfFlyingInterceptors);
				printf("Total num of interceptors: %d\n", InterceptorsList.NumOfInterceptors);
				// After manager notified "END_OF_ROUND" we notify interceptors on end of round
				printf("Notifying interceptors on end of round\n");
				NotifyInterceptorsOnEndOfRound(&InterceptorsList);
				NotifyClockEndOfRound(ClockSocket);
				// Wait for a new round to begin
				RoundNum = WaitForClockToNotifyBeginningOfRound(ClockSocket);
				if (RoundNum == -1)
				{
					PrintErrorAndExit(ERROR_RECEIVING_MESSAGE);
				}
				break;
			case ACTION_LAUNCH_INTERCEPTOR:
			{
				// Receive info on the rocket and launch an interceptor if there is one. Then send launch result to manager.
				BOOL LaunchRequestRes;
				TPosition RocketPosition;
				TVelocity RocketVelocity;
				int RocketID;
				ReceiveVector(&RocketPosition, ManagerSocket);
				ReceiveVector(&RocketVelocity, ManagerSocket);
				ReceiveInteger(&RocketID, ManagerSocket);
				printf("Received launch request from manager. Rocket information:\n");
				printf("Position: (%g, %g), Velocity: (%g, %g), ID: %d\n", RocketPosition.x, RocketPosition.y, RocketVelocity.x, RocketVelocity.y, RocketID);
				LaunchRequestRes = LaunchInterceptor(RocketPosition, RocketVelocity, RocketID, &InterceptorsList);
				printf("Launch request result: %s", LaunchRequestRes ? "Accepted\n" : "Refused\n");
				SendLaunchRequestResToManager(LaunchRequestRes, ManagerSocket);
				if (LaunchRequestRes == TRUE)
					InterceptorsList.NumOfFlyingInterceptors++;
				break;
			}
			case ACTION_NOTIFY_INTERCEPTOR_TO_CHANGE_BATTERY:
			{
				//We identify the interceptor by the rocket after which he is chasing.
				int ChasedRocketID, NewBatteryPort;
				char *NewBatteryIP = NULL;
				ReceiveInteger(&ChasedRocketID, ManagerSocket);
				ReceiveString(&NewBatteryIP, ManagerSocket);
				ReceiveInteger(&NewBatteryPort, ManagerSocket);
				NotifyInterceptorToSwitchBattery(ChasedRocketID, NewBatteryIP, NewBatteryPort, &InterceptorsList);
				printf("Notified the interceptor chasing rocket %d to switch to battery %s, %d\n", ChasedRocketID, NewBatteryIP, NewBatteryPort);
				break;
			}
			case ACTION_ROCKET_EXPLODED:
			{
				int ChasedRocketID;
				TransferResult_t TrnsRes;
				TInterceptor *InterceptorToSelfDestruct;
				ReceiveInteger(&ChasedRocketID, ManagerSocket);
				printf("BOOOOM! The rocket %d has exploded! Notifying the chasing interceptor to self destruct\n", ChasedRocketID);
				InterceptorToSelfDestruct = GetInterceptorByRocketID(&InterceptorsList, ChasedRocketID);
				TrnsRes = SendActionType(ACTION_SELF_DESTRUCT, InterceptorToSelfDestruct->Socket);
				DeleteInterceptor(&InterceptorsList, InterceptorToSelfDestruct);
				printf("Notified interceptor to self destruct and deleted it from the list.\n");
				break;
			}
			case ACTION_UPDATE_POSITIONS_MAP:
			{
				int RocketID;
				TPosition RocketPosition;
				TVelocity RocketVelocity;
				TInterceptor *Interceptor = NULL;
				ReceiveInteger(&RocketID, ManagerSocket);
				ReceiveVector(&RocketPosition, ManagerSocket);
				ReceiveVector(&RocketVelocity, ManagerSocket);
				printf("Received rocket %d position update. \n ", RocketID);
				printf("Position: (%.3g, %.3g). Velocity: (%.3g, %.3g)\n", RocketPosition.x, RocketPosition.y, RocketVelocity.x, RocketVelocity.y);
				printf("Sending information to its interceptor.\n");
				Interceptor = GetInterceptorByRocketID(&InterceptorsList, RocketID);
				SendActionType(ACTION_UPDATE_INTERCEPTOR_ON_ROCKET_INFO, Interceptor->Socket);
				SendVector(RocketPosition, Interceptor->Socket);
				SendVector(RocketVelocity, Interceptor->Socket);
				break;
			}
			case ACTION_END_OF_GAME:
			{
				closesocket(ClockSocket);
				PrintEndOfGame();
				exit(1);
			}
		}
	}
}

/*oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO*/
//				END OF Main Battery Function Implementation
/*oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO*/

/*oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO*/
//					Internal Functions Implementations
/*oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO*/
TInterceptor* GetInterceptorByRocketID(TInterceptorsList *InterceptorsList, int RocketID)
{
	TInterceptor *CurrentInterceptor = InterceptorsList->FirstInterceptor;
	while ((CurrentInterceptor != NULL) && (CurrentInterceptor->RocketID != RocketID))
	{
		CurrentInterceptor = CurrentInterceptor->NextInterceptor;
	}
	if (CurrentInterceptor != NULL)
	{
		return CurrentInterceptor;
	}
	return NULL;
}

BOOL NotifyInterceptorToSwitchBattery(int ChasedRocketID, char *NewBatteryIP, int NewBatteryPort, TInterceptorsList *InterceptorsList)
{
	TInterceptor *CurrentInterceptor = InterceptorsList->FirstInterceptor;
	while ((CurrentInterceptor != NULL) && (CurrentInterceptor->RocketID != ChasedRocketID))
	{
		CurrentInterceptor = CurrentInterceptor->NextInterceptor;
	}
	if (CurrentInterceptor != NULL)
	{
		TransferResult_t TrnsRes;
		TrnsRes = SendActionType(ACTION_NOTIFY_INTERCEPTOR_TO_CHANGE_BATTERY, CurrentInterceptor->Socket);
		if (TrnsRes == TRNS_SUCCEEDED)
		{
			SendActionType(ACTION_CHANGE_BATTERIES, ManagerSocket);
			SendString(NewBatteryIP, CurrentInterceptor->Socket);
			SendInteger(NewBatteryPort, CurrentInterceptor->Socket);
			// the interceptor will now register with the new battery. 
			printf("LOG: Notified interceptor chasing rocket %d to switch batteries\n", ChasedRocketID);
			printf("     To the battery with IP: %s and Port: %d\n", NewBatteryIP, NewBatteryPort);
			DeleteInterceptor(InterceptorsList, CurrentInterceptor);
		}
		else
		{
			SendActionType(ACTION_INTERCEPTED, ManagerSocket);
		}
		return TRUE;
	}
	return FALSE; 
}

BOOL LaunchInterceptor(TVelocity RocketVelocity, TPosition RocketPosition, int RocketID, TInterceptorsList* InterceptorsList)
{
	TInterceptor *CurrentInterceptor = InterceptorsList->FirstInterceptor;
	while ((CurrentInterceptor != NULL) && (CurrentInterceptor->Status != M_STATUS_IN_BATTERY))
	{
		CurrentInterceptor = CurrentInterceptor->NextInterceptor;
	}
	if (CurrentInterceptor != NULL)
	{
		CurrentInterceptor->RocketID = RocketID;
		CurrentInterceptor->Status = M_STATUS_ACTIVE;
		SendActionType(ACTION_LAUNCH_INTERCEPTOR, CurrentInterceptor->Socket);
		SendInteger(RocketID, CurrentInterceptor->Socket);
		SendVector(RocketPosition, CurrentInterceptor->Socket);
		SendVector(RocketVelocity, CurrentInterceptor->Socket);
		return TRUE;
	}
	return FALSE;
}

BOOL SendLaunchRequestResToManager(BOOL RequestRes, SOCKET ManagerSocket)
{
	if (SendBOOL(RequestRes, ManagerSocket) == TRNS_SUCCEEDED)
		return TRUE;
	return FALSE;
}

void AcceptConnectionsFromInterceptorsThread(TAcceptConncectionsArgs *AcceptConnectionsArgs)
{
	TInterceptorsList *InterceptorsList = AcceptConnectionsArgs->InterceptorsList;
	SOCKET MainSocket = AcceptConnectionsArgs->MainSocket;
	TPosition BatteryPosition = AcceptConnectionsArgs->BatteryPosition;

	TActionType RecAction;
	TInterceptor *AddedInterceptor = NULL;

	while (1)
	{
		SOCKET Socket = AcceptConnection(MainSocket);
		ReceiveActionType(&RecAction, Socket);
		switch (RecAction)
		{
			case ACTION_REGISTRATION:
				SendVector(BatteryPosition, Socket);
				AddedInterceptor = AddInterceptorToBattery(InterceptorsList);
				AddedInterceptor->Socket = Socket;
				AddedInterceptor->Status = M_STATUS_IN_BATTERY;
				AddedInterceptor->RocketID = 0;
				AddedInterceptor->Velocity.x = 0;
				AddedInterceptor->Velocity.y = 0;
				AddedInterceptor->Position = BatteryPosition;
				//InterceptorsList->NumOfInterceptors++;
				break;
			case ACTION_CHANGE_BATTERIES:
				AddedInterceptor = AddInterceptorToBattery(InterceptorsList);
				ReceiveInteger(&(AddedInterceptor->RocketID), Socket);
				AddedInterceptor->Socket = Socket;
				AddedInterceptor->Status = M_STATUS_ACTIVE;
				AddedInterceptor->Velocity.x = 0;
				AddedInterceptor->Velocity.y = 0;
				AddedInterceptor->Position.x = 0;
				AddedInterceptor->Position.y = 0;
				printf("Interceptor chasing #%d registered.\n", AddedInterceptor->RocketID);
				SendActionType(ACTION_NOTIFY_INTERCEPTOR_TO_CHANGE_BATTERY, ManagerSocket);
				printf("Notified manager that an interceptor has successfuly switched batteries.");
				//InterceptorsList->NumOfInterceptors++;
				InterceptorsList->NumOfFlyingInterceptors++;
				break;
			default:
				PrintErrorAndExit(GENERAL_ERROR);
				break;
		}
	}
}


TInterceptor* AddInterceptorToBattery(TInterceptorsList* InterceptorsList)
{
	TInterceptor* AddedInterceptor = (TInterceptor*)malloc(sizeof(TInterceptor));
    if(AddedInterceptor == NULL)
	{
		PrintErrorAndExit(ERROR_ALLOCATING_MEMORY);
	}
	
	if (InterceptorsList != NULL)
	{
		AddedInterceptor->NextInterceptor = InterceptorsList->FirstInterceptor;
	}
	InterceptorsList->FirstInterceptor = AddedInterceptor ;	
	InterceptorsList->NumOfInterceptors++;
	return InterceptorsList->FirstInterceptor;
}
 
void DeleteInterceptor(TInterceptorsList *InterceptorsList, TInterceptor *InterceptorToDelete)
{
	TInterceptor *CurrentInterceptor = InterceptorsList->FirstInterceptor;
	TInterceptor *PreviousInterceptor = NULL;
	// If the list is empty, nothing is deleted.
	if (CurrentInterceptor == NULL) 
	{
		printf("DEBUG: List is empty, no interceptor was deleted\n");
		return;
	}

	// if the interceptor to be deleted is the first interceptor in the list, change the second interceptor in list to be the first, and free the first type.
	if (InterceptorsList->FirstInterceptor == InterceptorToDelete)
	{
		InterceptorsList->FirstInterceptor = CurrentInterceptor->NextInterceptor;
		if (CurrentInterceptor->Status == M_STATUS_ACTIVE)
		{
			InterceptorsList->NumOfFlyingInterceptors--;
		}
		free(CurrentInterceptor);
		// decrease the number of types in supply
		InterceptorsList->NumOfInterceptors--;
		return;
	}
	else
	{ //search for the right interceptor to delete
		while ((CurrentInterceptor != NULL) && (CurrentInterceptor != InterceptorToDelete))
		{
			PreviousInterceptor = CurrentInterceptor;
			CurrentInterceptor = CurrentInterceptor->NextInterceptor;
		}
		if (NULL != CurrentInterceptor)
		{
			PreviousInterceptor->NextInterceptor = CurrentInterceptor->NextInterceptor;
			if (CurrentInterceptor->Status == M_STATUS_ACTIVE)
			{
				InterceptorsList->NumOfFlyingInterceptors--;
			}
			free(CurrentInterceptor);
			InterceptorsList->NumOfInterceptors--;
			return;
		}
		// if the interceptor is not found, report error
			printf("Error. Tried to delete a interceptor which is not in the list\n"); 
			return;
	}
}



BOOL SelfDistructInterceptor(TInterceptorsList* InterceptorsList, int ChasedRocketID) 
{
	TInterceptor *CurrentInterceptor = InterceptorsList->FirstInterceptor;
	while ((CurrentInterceptor != NULL) && (CurrentInterceptor->RocketID != ChasedRocketID))
	{
		CurrentInterceptor = CurrentInterceptor->NextInterceptor;
	}
	if (CurrentInterceptor == NULL)
	{
		printf("Interceptor not in interceptors list. can't self destruct\n");
		return FALSE;
	}
	else
	{
		SendActionType(ACTION_SELF_DESTRUCT, CurrentInterceptor->Socket);
		DeleteInterceptor(InterceptorsList, CurrentInterceptor);
	}
	return TRUE;
}

void NotifyInterceptorsOnEndOfRound(TInterceptorsList *InterceptorsList)
{
	TInterceptor *CurrentInterceptor = InterceptorsList->FirstInterceptor;
	while (CurrentInterceptor != NULL)
	{
		SendActionType(ACTION_END_OF_ROUND, CurrentInterceptor->Socket);
		CurrentInterceptor = CurrentInterceptor->NextInterceptor;
	}
}

/*oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO*/
//					END OF Internal Functions Implementations
/*oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO*/